﻿#pragma once
#include "discrete_face_utils.hxx"
class QuadTree {
public:
    point_vector points_;
    edge_vector h_edges_, v_edges_;
    std::vector<Box> leaf_rect_;
    QuadTree(FACE* f, const Box box, double nt, double st, std::vector<SPApar_pos> vertex_set);
    ~QuadTree();

private:
    struct Node {
        std::array<std::unique_ptr<Node>, 4> children;
        std::vector<SPApar_pos> vertex_set;
    };
    // u线
    std::unordered_map<double, curve*> u_iso_lines, v_iso_lines;
    FACE* face_;
    Box mBox_;
    bool need_quad_first_{ false };
    const double distance_tolerance_, angle_tolerance_;
    // bool isLeaf(const Node* node) const;
    std::unique_ptr<Node> mRoot_;
    /**
     * @brief 构建四叉树结构，用于管理和优化面片的空间分割。
     *
     * 该函数递归地将给定的空间区域分割成更小的区域，直到满足特定的拟合条件或达到一定的深度限制。
     * 在每个分割的区域中，会生成特定的采样点，用于后续的处理。
     *
     * @param[in] box 当前区域的边界盒，包含了当前区域的位置和尺寸信息。
     * @param[in] root 当前区域对应的四叉树节点。
     * @param[in] dep 当前的递归深度。
     */

     //
    void BuildTreeByBin(const Box& box, int dep);
    /**
     * @brief 生成四叉树的点和边。
     *
     * 该函数通过遍历四叉树的叶节点，生成点和边的索引，并将其存储在相应的容器中。
     */
    void GenaratePointsAndEdges();
    bool isLeaf(const Node* node) const;
    Box GetRootBox() const;
};

/**
 * 检查给定的矩形区域是否可以通过对角线分割成两个三角形，以满足特定的拟合条件。
 *
 * 该函数首先定义了两组三角形，每组对应于矩形沿一个对角线分割的结果。然后，它计算矩形四个角点
 * 和中心点的位置，以及沿两个对角线的中点位置。根据中心点到这两个中点的距离，选择一个对角线
 * 进行分割，并检查沿该对角线分割得到的两个三角形是否都满足给定的角度和距离容差条件。
 *
 * @param[in] box 一个表示矩形区域的Box对象，包含矩形的位置和尺寸信息。
 * @return 返回一个布尔值，表示是否可以通过对角线分割的两个三角形拟合。
 */
bool CheckFitAndJudgeDiagonal(FACE* face, const Box& box, const double angle_tolerance, const double distance_tolerance);
class spline_faceter : abstract_faceter {
private:
    spline* spl = nullptr;

    int seperation_cnt = 0;
    bool singular_ule = false;
    bool singular_uri = false;
    bool singular_vle = false;
    bool singular_vri = false;
    bool has_per{ false };
    bool closed_u = false;
    bool closed_v = false;
    bool periodic_u{ false };
    bool periodic_v{ false };
    bool no_boundary{ true };
    bool need_add_boundary_u_{ false };
    bool need_add_boundary_v_{ false };
    BoundaryAnalyzer ba;
    std::vector<point_vector> loops;
    double approx_tol_{ SPAresabs };
    void LoopProcess();
    void GetLoops();
    /**
     * @brief 处理面和环的交点，更新点和边的集合。
     *
     * 该函数主要执行以下步骤：
     * 1. 移除重复的点和边。
     * 2. 判断点是否在多边形内部，并处理边的交点。
     * 3. 处理水密性问题
     * 4. 标记限制边
     *
     * @param tree 通过树结构生成的初始网格。
     * @param loops_points 环的点集。
     * @param loops_edges 环的边集。
     * @param res_points 结果点集。
     * @param res_edges 结果边集。
     * @param markedEdge 标记的边集。
     */
    void ProcessFaceAndLoopsIntersection(QuadTree& tree, point_vector& loops_points, edge_vector& loops_edges, point_vector& res_points, edge_vector& res_edges, CDT::EdgeUSet& markedEdge);
    /**
     * @brief 将通过四叉树生成的网格附加到面上。
     *
     * 该函数首先将四叉树生成的点集合并到现有点集中，然后使用CDT算法进行三角剖分。
     * 剖分后，对生成的三角形进行后处理，并构建一个索引网格（INDEXED_MESH），最后将该网格附加到指定的面上。
     *
     * @param[in] tree 四叉树，包含用于生成网格的点集。
     */
    void attachMeshByQuad(QuadTree& tree);

protected:
    void init() override;
    void decideUVlen() override;
    bool getLoops() override;
    void peripheryProcess() override;

    /**
     * @brief 处理U方向上的分割过程
     *
     * 该函数主要处理在V方向上的分割，特别是当曲面在V方向上闭合时，需要特别处理穿越边界的情况。
     *
     * @return bool 返回处理结果，当前实现总是返回false。
     */
    bool USeperationProcess() override;
    /**
     * @brief 处理U方向分割过程
     *
     * 该函数处理垂直分割过程，主要用于处理在垂直方向上的分割和连接，确保几何形状的正确性。
     *
     * @return bool 返回处理过程是否成功。当前实现总是返回false。
     */
    bool VSeperationProcess() override;
    /**
     * @brief 处理网格中的孔洞，通过将它们分割成更小的Loop并进行三角化。
     *
     * 该函数遍历网格中的所有孔洞循环。对于每个孔洞Loop，它根据给定的容差将Loop分割成更小的Loop。
     * 然后通过向网格数据结构添加点和边来对这些更小的Loop进行三角化。
     */
    void holeProcess() override;
    void attachMesh() override;

public:
    spline_faceter(FACE* f, double nt = 0, double st = 0) : abstract_faceter(f, nt, st), ba(f) {}
    outcome facet() override;
};

/**
 * 此文件保存离散化样条面的函数.
 */
outcome facet_face_spline(FACE* f, double nt = 0, double st = 0);
